package imoney.shared.model;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;

import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;

/**
 * The class modeling a group, which is a list of integers recording the IDs of
 * the member (each int is a member).
 * @author Arnaud PELOQUIN
 */
@PersistenceCapable
public class Group extends Registreable implements Serializable {

	/**
	 * Date of the last modification requiring new version.
	 */
	private static final long serialVersionUID = 13062011L;

	@Persistent
	private ArrayList<String> membres;
	@Persistent
	private String name;
	@Persistent
	private String banker;
	
	// Creation date ?
	
	/**
	 * Public constructor to create a new group with a list of members.
	 * If a new instance of a group is needed without knowing yet the members,
	 * call Group(String name).
	 * 
	 * @param membs : the integer list (ids of the members)
	 * @param nom : the string defining the name of the group
	 * @param bank : the pseudo of the banker.
	 */
	public Group(ArrayList<String> membs, String nom, String bank){
		/*
		 *  TODO : est-ce que le banquier doit forcément appartenir au groupe ?
		 *  -> pas forcément si on veut un seul banquier pour plusieurs groupes
		 *  dont l'intersection globale est vide. Le choix sera laissé à l'utilisateur
		 *  donc au final on le laisse mais pas sur qu'il soit utilisé
		 *  Idée : faire un check informatif pour surveiller les bugs et pas plus
		 */
		setMembres(membs);
		name = nom;
		banker = bank;
	}
	/**
	 * Creates an empty group with the given name. The banker is void,
	 * and an error will occur if the group is used as such.
	 * @param name : the name of the group.
	 */
	public Group(String name){
		this(new ArrayList<String>(), name, "void banker");
	}
	
	/**
	 * Empty constructor calling <code>Group(String name)<code>
	 * with as default name the date of creation.
	 */
	public Group(){
		this("empty constructor group");
		Date date = new Date();
		String stringdate = date.toString();
		this.setName("default group created the : "+stringdate);
	}
	
	/**
	 * Updates the name of the group.
	 * @param name : the new name of the group.
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * Returns the current name of the group.
	 * @return name : the current name of the group.
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * A group might already have people inside it, so calls of addMembre() and deleteMembre() are
	 * encouraged instead of this method. 
	 * @param membres : the member list that will define the group. A member is defined by its googleID
	 */
	public void setMembres(ArrayList<String> membersGoogleIDs) {
			this.membres = membersGoogleIDs;
	}
	
	/**
	 * Adds the member to this group if not present. If the member
	 * is present the methods return silently.
	 * @param googleID
	 */
	public void addMembre(String googleID){
		if(membres.indexOf(googleID) == -1) {
			membres.add(googleID);
		}
	}
	
	/**
	 * Removes the specified member if present.
	 * If the memeber is not present, the method returns silently.
	 * @param googleID : the userID of the person to remove.
	 */
	public void deleteMembre(String googleID){
		membres.remove(googleID);
	}
	
	/**
	 * Get the current membres
	 * @return membres : the list of the IDs of the current members.
	 */
	public ArrayList<String> getMembres() {
		return membres;
	}
	
	/**
	 * Sets the person ID that should be granted exclusive access to deleteTransaction().
	 * @param banker
	 */
	public void setBanker(String banker) {
		this.banker = banker;
	}
	
	public String getBanker() {
		return banker;
	}
	
	public String toString(){
		return "ID: "+getId()+", nom: "+name+", banquier: "+banker+", people: "+membres.toString();
	}
	
	@Override
	/**
	 * This query enables to check only for repetition in group names. It's been chosen not to check if the people are the same in different
	 * groups, for performance, but also to enable the same group of people to manage different events with differents bankers if
	 * they want. As the name will be different, there should be no confusion. Finally, an option to delete a group will ensure
	 * no trash group remains to disturb the user.
	 */
	public String getAvailabilityQuery() {
		return "select from "+Group.class.getName()+" where name == '"+name+"'";
	}
	@Override
	public String getAvailabilityExceptionMessage() {
		return "Group name '"+getName()+"' is already in use.";
	}

}
